/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package patterns;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class CommandTest {

    public static void main(String[] args) throws IOException {
        System.out.println("Program start");
        TimedCollection<Integer> timed = new TimedCollection<Integer>(
                new HashSet<Integer>());
        //
        timed.add(123456);
        timed.add(654321);
        timed.cancelOperations();
        //
        timed.add(0);
        timed.add(1);
        timed.add(2);
        timed.remove(123);
        //
        System.in.read();
    }
}

class TimedCollection<E> {

    private final Collection<E> collection;
    private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    private List<Runnable> operations = Collections.synchronizedList(new LinkedList<Runnable>());

    TimedCollection(Collection<E> collection) {
        this.collection = collection;
        this.executor.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                Runnable[] ops;
                synchronized (operations) {
                    ops = operations.toArray(new Runnable[0]);
                    operations.clear();
                }
                for (Runnable op : ops) {
                    op.run();
                }
            }
        }, 0, 1, TimeUnit.SECONDS);
    }

    public void add(final E elem) {
        operations.add(new Runnable() {
            public void run() {
                System.out.println("add " + elem);
                collection.add(elem);
            }
        });
    }

    public void remove(final E elem) {
        operations.add(new Runnable() {
            @Override
            public void run() {
                System.out.println("remove " + elem);
                collection.remove(elem);
            }
        });
    }

    public void cancelOperations() {
        operations.clear();
    }
}
